<template>
    <div v-show="visible" class='mask-wrapper-shawn' :style="`background-color:${bgColor}`">
         <div class="content">
             <div class="animation-wrapper">
                 <slot>
                     <div class="animation-cube" v-if="animate === 'rotate-cube'"></div>
                     <div class="animation-ring" v-else-if="animate === 'progress-ring'" >
                         <span :style="`color:${getContrastColor(bgColor)}`">{{ progress >= 100 ? '完成':progress + '%' }}</span>
                         <svg class="progress-ring" :width="ringSize" :height="ringSize">
                             <circle class="progress-ring__circle" stroke="#f2f2f2" :stroke-width="strokeWidth" fill="transparent" :r="radius" :cx="center" :cy="center"></circle>
                             <circle class="progress-ring__path" :stroke="strokeColor" :stroke-width="strokeWidth" fill="transparent" :r="radius" :cx="center" :cy="center" :stroke-dasharray="circleDasharray" :stroke-dashoffset="circleDashoffset"></circle>
                         </svg>
                     </div>
                 </slot>
             </div>
             <div class="loading-text" v-if="animate === 'rotate-cube'">
                 <slot name="text">
                     <p :style="`color:${getContrastColor(bgColor)}`">加载中...</p>
                 </slot>
             </div>
         </div>
    </div>
 </template>
 <script setup>
 import { ref, watch, computed } from 'vue';
 const isModalOpen = ref(false);
 const progress = ref(0);
 const props = defineProps({
   bgColor:{//遮罩背景色
       type:String,
       default:'#0000009c'
   },
   visible:{//是否显示遮罩
       type:Boolean,
       default:false
   },
   animate:{//动画类型   --rotate-cube  --progress-ring
     type:String,
     default:'rotate-cube'
   },
   progress:{//进度条 0-100
       type:Number,
       default:0
   },
   ringSize: { // 环形进度条大小
     type: Number,
     default: 100
   },
   strokeWidth: { // 环形进度条宽度
     type: Number,
     default: 6
   },
   strokeColor: { // 环形进度条颜色
     type: String,
     default: '#74dc5ae8'
   }
 });
 
 watch(() => props.visible, (newValue) => {
   if (newValue) { openModal();} else { closeModal();}
 });
 watch(() => props.progress, (newValue) => {
   let value = newValue > 100 ? 100 : newValue;
   progress.value = value;
 });
 
 // 打开遮罩层
 const openModal = () => {
   isModalOpen.value = true;
   document.body.style.overflow = 'hidden';
   document.addEventListener('wheel', preventScroll, { passive: false });
 };
 
 // 关闭遮罩层
 const closeModal = () => {
   isModalOpen.value = false;
   document.body.style.overflow = 'auto';
   document.removeEventListener('wheel', preventScroll);
 };
 
 //阻止滚动
 const preventScroll = (event) => {
   if (isModalOpen.value) {
     event.preventDefault();
   }
 };
 
 // 计算反差颜色
 function getContrastColor(hex) {
   const r = parseInt(hex.slice(1, 3), 16);
   const g = parseInt(hex.slice(3, 5), 16);
   const b = parseInt(hex.slice(5, 7), 16);
   const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
   return luminance > 0.5 ? '#000000' : '#FFFFFF';
 }
 
 const radius = computed(() => {
   return (props.ringSize - props.strokeWidth) / 2;
 });
 
 const center = computed(() => {
   return props.ringSize / 2;
 });
 
 const circleDasharray = computed(() => {
   return 2 * Math.PI * radius.value;
 });
 
 const circleDashoffset = computed(() => {
   return circleDasharray.value - (progress.value / 100) * circleDasharray.value;
 });
 </script>
 
 <style>
     .mask-wrapper-shawn{
         width: 100%;
         height: 100%;
         position: fixed;
         left: 0;
         top: 0;
         padding: 0;
         margin: 0;
         z-index: 9999;
         display: flex;
         align-items: center;
         justify-content: center;
     }
     .animation-wrapper{
          position: relative;
          width: 6vw;
          height: 6vw;
          display: flex;
          align-items: center;
          justify-content: center;
     }
     .loading-text p{
         text-align: center;
         font-size: 1 rem;
     }
     .animation-cube {
         width: 3vw;
         height: 3vw;
         border-radius:10%;
         animation: rotate-cube 1s ease infinite;
     }
     .animation-ring{
         width: 5vw;
         height: 5vw;
         position: relative;
         display: flex;
         align-items: center;
         justify-content: center;
     }
     .animation-ring span{
         position: absolute;
         top: 50%;
         left: 50%;
         transform: translate(-50%, -50%);
         font-size: 1rem;
     }
     @keyframes rotate-cube {
         0% {
             transform: translateY(5vh);
             background: linear-gradient(135deg, #48ff00, #FF8C00);
         }
         50% {
             transform: rotate(-360deg);
         }
         51% {
             transform: translateY(0) rotate(-360deg);
         }
         100% {
             transform:  translateY(0) rotate(0deg);
             background: linear-gradient(-135deg, #00ffdd, #ff4800);
         }
     }
 
 .progress-ring {
   display: block;
   box-sizing: border-box;
 }
 
 .progress-ring__circle {
   transition: stroke-dashoffset 0.35s;
   transform: rotate(-90deg);
   transform-origin: 50% 50%;
 }
 
 .progress-ring__path {
   stroke-linecap: round;
   transition: stroke-dashoffset 0.35s;
   transform: rotate(-90deg);
   transform-origin: 50% 50%;
 }
 </style>